package com.cloud.weixin.handler;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.cloud.weixin.project.cons.WxCons;
import com.cloud.weixin.project.mapper.WxUserMapper;
import com.cloud.weixin.project.model.entity.WxAutoReply;
import com.cloud.weixin.project.model.entity.WxMsg;
import com.cloud.weixin.project.model.entity.WxUser;
import com.cloud.weixin.project.service.IWxAutoReplyService;
import com.cloud.weixin.project.service.IWxMsgService;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
import me.chanjar.weixin.mp.builder.outxml.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 消息回复处理
 */
@Component
@AllArgsConstructor
public class MsgHandler extends AbstractHandler {

    @Autowired
    private IWxAutoReplyService wxAutoReplyService;
    @Autowired
    private IWxMsgService wxMsgService;
    @Resource
    private WxUserMapper userMapper;

    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
                                    Map<String, Object> context, WxMpService wxMpService,
                                    WxSessionManager sessionManager) {
        //组装回复消息
        if (!wxMessage.getMsgType().equals(WxConsts.XmlMsgType.EVENT)) {
            WxMpXmlOutMessage rs;
            //TODO 可以选择将消息保存到本地
            WxUser wxUser = SqlHelper.getObject(userMapper.selectList(Wrappers.<WxUser>lambdaQuery()
                    .eq(WxUser::getOpenId, wxMessage.getFromUser())));
            if (Objects.isNull(wxUser)) {
                return null;
            }
            if (WxConsts.KefuMsgType.TEXT.equals(wxMessage.getMsgType())) {//1、先处理是否有文本关键字回复
                //先全匹配
                List<WxAutoReply> listWxAutoReply = wxAutoReplyService.list(Wrappers
                        .<WxAutoReply>query().lambda()
                        .eq(WxAutoReply::getType, WxCons.WX_AUTO_REPLY_TYPE_KEY)
                        .eq(WxAutoReply::getRepMate, WxCons.WX_REP_MATE_FULL)
                        .eq(WxAutoReply::getReqKey, wxMessage.getContent()));
                if (listWxAutoReply != null && listWxAutoReply.size() > 0) {
                    rs = getWxMpXmlOutMessage(wxMessage, listWxAutoReply, wxUser, wxMsgService);
                    if (rs != null) {
                        return rs;
                    }
                }
                //再半匹配
                listWxAutoReply = wxAutoReplyService.list(Wrappers
                        .<WxAutoReply>query().lambda()
                        .eq(WxAutoReply::getType, WxCons.WX_AUTO_REPLY_TYPE_KEY)
                        .eq(WxAutoReply::getRepMate, WxCons.WX_REP_MATE_HALF)
                        .like(WxAutoReply::getReqKey, wxMessage.getContent()));
                if (listWxAutoReply != null && listWxAutoReply.size() > 0) {
                    rs = getWxMpXmlOutMessage(wxMessage, listWxAutoReply, wxUser, wxMsgService);
                    if (rs != null) {
                        return rs;
                    }
                }
            }
            //2、再处理消息回复
            List<WxAutoReply> listWxAutoReply = wxAutoReplyService.list(Wrappers
                    .<WxAutoReply>query().lambda()
                    .eq(WxAutoReply::getType, WxCons.WX_AUTO_REPLY_TYPE_MSG)
                    .eq(WxAutoReply::getReqType, wxMessage.getMsgType()));
            rs = getWxMpXmlOutMessage(wxMessage, listWxAutoReply, wxUser, wxMsgService);
            return rs;
        }
        return null;

    }

    /**
     * 组装回复消息，并记录消息
     *
     * @param wxMessage
     * @param listWxAutoReply
     * @return
     */
    public static WxMpXmlOutMessage getWxMpXmlOutMessage(WxMpXmlMessage wxMessage, List<WxAutoReply> listWxAutoReply, WxUser wxUser,
                                                         IWxMsgService wxMsgService) {
        WxMpXmlOutMessage wxMpXmlOutMessage = null;
        //记录接收消息
        WxMsg wxMsg = new WxMsg();
        wxMsg.setWxUserId(wxUser.getId());
        wxMsg.setNickName(wxUser.getNickName());
        wxMsg.setHeadImgUrl(wxUser.getHeadImgUrl());
        wxMsg.setType(WxCons.WX_MSG_TYPE_USER2MP);
        wxMsg.setRepEvent(wxMessage.getEvent());
        wxMsg.setRepType(wxMessage.getMsgType());
        wxMsg.setRepMediaId(wxMessage.getMediaId());
        if (WxConsts.XmlMsgType.TEXT.equals(wxMessage.getMsgType())) {
            wxMsg.setRepContent(wxMessage.getContent());
        }
        if (WxConsts.XmlMsgType.VOICE.equals(wxMessage.getMsgType())) {
            wxMsg.setRepName(wxMessage.getMediaId() + "." + wxMessage.getFormat());
            wxMsg.setRepContent(wxMessage.getRecognition());
        }
        if (WxConsts.XmlMsgType.IMAGE.equals(wxMessage.getMsgType())) {
            wxMsg.setRepUrl(wxMessage.getPicUrl());
        }
        if (WxConsts.XmlMsgType.LINK.equals(wxMessage.getMsgType())) {
            wxMsg.setRepName(wxMessage.getTitle());
            wxMsg.setRepDesc(wxMessage.getDescription());
            wxMsg.setRepUrl(wxMessage.getUrl());
        }
        if (WxConsts.MediaFileType.FILE.equals(wxMessage.getMsgType())) {
            wxMsg.setRepName(wxMessage.getTitle());
            wxMsg.setRepDesc(wxMessage.getDescription());
        }
        if (WxConsts.XmlMsgType.VIDEO.equals(wxMessage.getMsgType())) {
            wxMsg.setRepThumbMediaId(wxMessage.getThumbMediaId());
        }
        if (WxConsts.XmlMsgType.LOCATION.equals(wxMessage.getMsgType())) {
            wxMsg.setRepLocationX(wxMessage.getLocationX());
            wxMsg.setRepLocationY(wxMessage.getLocationY());
            wxMsg.setRepScale(wxMessage.getScale());
            wxMsg.setRepContent(wxMessage.getLabel());
        }
        wxMsg.setReadFlag("0");
        wxMsgService.save(wxMsg);
        //推送websocket
//        String destination = WebSocketConstant.USER_DESTINATION_PREFIX + WebSocketConstant.WX_MSG + wxMsg.getWxUserId();
        if (listWxAutoReply != null && listWxAutoReply.size() > 0) {
            WxAutoReply wxAutoReply = listWxAutoReply.get(0);
            //记录回复消息
            wxMsg = new WxMsg();
            wxMsg.setWxUserId(wxUser.getId());
            wxMsg.setNickName(wxUser.getNickName());
            wxMsg.setHeadImgUrl(wxUser.getHeadImgUrl());
            wxMsg.setType(WxCons.WX_MSG_TYPE_MP2USER);
            wxMsg.setRepType(wxAutoReply.getRepType());

            if (WxConsts.KefuMsgType.TEXT.equals(wxAutoReply.getRepType())) {//文本
                wxMsg.setRepContent(wxAutoReply.getRepContent());
                wxMpXmlOutMessage = new TextBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).content(wxAutoReply.getRepContent()).build();
            }
            if (WxConsts.KefuMsgType.IMAGE.equals(wxAutoReply.getRepType())) {//图片
                wxMsg.setRepName(wxAutoReply.getRepName());
                wxMsg.setRepUrl(wxAutoReply.getRepUrl());
                wxMsg.setRepMediaId(wxAutoReply.getRepMediaId());
                wxMpXmlOutMessage = new ImageBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).mediaId(wxAutoReply.getRepMediaId()).build();
            }
            if (WxConsts.KefuMsgType.VOICE.equals(wxAutoReply.getRepType())) {
                wxMsg.setRepName(wxAutoReply.getRepName());
                wxMsg.setRepUrl(wxAutoReply.getRepUrl());
                wxMsg.setRepMediaId(wxAutoReply.getRepMediaId());
                wxMpXmlOutMessage = new VoiceBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).mediaId(wxAutoReply.getRepMediaId()).build();
            }
            if (WxConsts.KefuMsgType.VIDEO.equals(wxAutoReply.getRepType())) {
                wxMsg.setRepName(wxAutoReply.getRepName());
                wxMsg.setRepDesc(wxAutoReply.getRepDesc());
                wxMsg.setRepUrl(wxAutoReply.getRepUrl());
                wxMsg.setRepMediaId(wxAutoReply.getRepMediaId());
                wxMpXmlOutMessage = new VideoBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).mediaId(wxAutoReply.getRepMediaId())
                        .title(wxAutoReply.getRepName()).description(wxAutoReply.getRepDesc()).build();
            }
            if (WxConsts.KefuMsgType.MUSIC.equals(wxAutoReply.getRepType())) {
                wxMsg.setRepName(wxAutoReply.getRepName());
                wxMsg.setRepDesc(wxAutoReply.getRepDesc());
                wxMsg.setRepUrl(wxAutoReply.getRepUrl());
                wxMsg.setRepHqUrl(wxAutoReply.getRepHqUrl());
                wxMsg.setRepThumbMediaId(wxAutoReply.getRepThumbMediaId());
                wxMsg.setRepThumbUrl(wxAutoReply.getRepThumbUrl());
                wxMpXmlOutMessage = new MusicBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
                        .thumbMediaId(wxAutoReply.getRepThumbMediaId())
                        .title(wxAutoReply.getRepName()).description(wxAutoReply.getRepDesc())
                        .musicUrl(wxAutoReply.getRepUrl()).hqMusicUrl(wxAutoReply.getRepHqUrl()).build();
            }
            if (WxConsts.KefuMsgType.NEWS.equals(wxAutoReply.getRepType())) {
                List<WxMpXmlOutNewsMessage.Item> list = new ArrayList<>();
                JSONArray array = JSONArray.parseObject(wxAutoReply.getContent()).getJSONArray("articles");
                WxMpXmlOutNewsMessage.Item t;
                for (Object o : array) {
                    JSONObject obj = (JSONObject) o;
                    t = new WxMpXmlOutNewsMessage.Item();
                    t.setTitle(obj.getString("title"));
                    t.setDescription(obj.getString("digest"));
                    t.setPicUrl(obj.getString("thumbUrl"));
                    t.setUrl(obj.getString("url"));
                    list.add(t);
                }
                wxMsg.setRepName(wxAutoReply.getRepName());
                wxMsg.setRepDesc(wxAutoReply.getRepDesc());
                wxMsg.setRepUrl(wxAutoReply.getRepUrl());
                wxMsg.setRepMediaId(wxAutoReply.getRepMediaId());
                wxMsg.setContent(wxAutoReply.getContent());
                wxMpXmlOutMessage = new NewsBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).articles(list).build();
            }
            wxMsgService.save(wxMsg);
        }
        return wxMpXmlOutMessage;
    }

}
